# -*- coding: utf-8 -*-
# https://blog.csdn.net/weixin_52040868
# 公众号：测个der
# 微信：qing_an_an

import datetime
import pyqtgraph as pg
from PySide6.QtGui import QColor, QFont, QPen
from PySide6.QtWidgets import QVBoxLayout
from pyqtgraph import DateAxisItem, PlotDataItem, AxisItem, PlotWidget
from pyqtgraph.Qt import QtCore


class TimeAxisItem(AxisItem):
    def __init__(self, orientation, *args, **kwargs):
        super().__init__(orientation, *args, **kwargs)

    def tickStrings(self, values, scale, spacing):
        return [datetime.datetime.fromtimestamp(value).strftime("%H:%M:%S.%f")[:-3] for value in values]


class DataPlotWidget:
    def __init__(self, ui):
        self.ui = ui
        # 创建布局
        self.layout = QVBoxLayout()
        self.ui.Chart_widget.setLayout(self.layout)

        # /////////////////生成示例数据/////////////////////
        self.timestamps = []
        self.data = []

        # 创建绘图窗口
        self.plot_widget = PlotWidget(pen=pg.mkPen(color='w', width=2))
        # 禁止自动缩放
        self.plot_widget.getPlotItem().getViewBox().enableAutoRange(axis=pg.ViewBox.YAxis, enable=False)
        # ////////////////////添加十字线////////////////////////
        self.vLine = pg.InfiniteLine(angle=90, movable=False)
        self.hLine = pg.InfiniteLine(angle=0, movable=False)
        self.plot_widget.addItem(self.vLine, ignoreBounds=True)
        self.plot_widget.addItem(self.hLine, ignoreBounds=True)

        # ///////////////////////////////////////////////////

        # //////////////设置时间轴///////////////////////////
        self.date_axis = TimeAxisItem(orientation='bottom')
        self.date_axis.setLabel(text='Time')

        # ///////////////////创建图形对象///////////////////
        # ///////////////////设置样式表////////////////////
        pg.setConfigOptions(antialias=True)
        pg.setConfigOption('background', 'w')
        pg.setConfigOption('foreground', 'k')
        self.plot = PlotDataItem(pen=pg.mkPen(color='w', width=2))  # 设置曲线的样式
        self.plot_widget.addItem(self.plot)

        # 创建文本项
        self.text_item = pg.TextItem(anchor=(0, 1))
        self.plot_widget.addItem(self.text_item)
        self.text_item.hide()

        # 连接鼠标移动事件
        self.plot_widget.scene().sigMouseMoved.connect(self.mouseMoved)
        # 链接鼠标点击事件
        self.plot_widget.scene().sigMouseClicked.connect(self.mouseClicked)
        # 存储鼠标点击的点的坐标
        self.clicked_timestamps = []
        self.clicked_points = []
        self.line_item = None

        self.ui.Chart_btn_clear.clicked.connect(self.clearGraph)

        # 将绘图窗口添加到布局中
        self.layout.addWidget(self.plot_widget)

    def clearGraph(self):
        """清除数据"""
        self.timestamps.clear()
        self.data.clear()
        # self.plot_widget.clear()
        # 重新绘制图表
        # self.plot.setData(self.timestamps, self.data)

    def mouseClicked(self, evt):
        """存入点击数据"""
        pos = self.plot_widget.mapFromScene(evt.scenePos())
        mousePoint = self.plot_widget.plotItem.vb.mapSceneToView(pos)
        timestamp = mousePoint.x()
        self.clicked_timestamps.append(timestamp)
        self.clicked_points.append((mousePoint.x(), mousePoint.y()))
        if len(self.clicked_timestamps) == 2:
            self.calculateAndProcessTimeDifference()
            self.drawConnectingLine()

    def calculateAndProcessTimeDifference(self):
        """计算点击数据"""
        timestamp1, timestamp2 = self.clicked_timestamps
        time_difference = timestamp2 - timestamp1
        # 进行时间差值的处理，保留两位小数，例如输出或其他操作
        self.ui.Chart_line.setText(str(round(time_difference, 2)) + " S")
        # 清空已点击的时间戳列表
        self.clicked_timestamps = []

    def drawConnectingLine(self):
        # 移除已存在的连接线
        if self.line_item is not None:
            for item in self.line_item:
                self.plot_widget.removeItem(item)
        # 获取点击点的坐标
        point1, point2 = self.clicked_points[-2:]
        x1, y1 = point1
        x2, y2 = point2
        # 创建并添加连接线，并设置样式
        line = pg.PlotCurveItem(x=[x1, x2], y=[y1, y2],
                                pen=pg.mkPen(color='g', width=1,
                                             style=QtCore.Qt.DashLine,
                                             cosmetic=True))
        self.plot_widget.addItem(line)
        # 创建起点和终点的形状
        start_point = pg.ScatterPlotItem(x=[x1], y=[y1], symbol='o', size=5, pen='g', brush='g')
        end_point = pg.ScatterPlotItem(x=[x2], y=[y2], symbol='o', size=5, pen='g', brush='g')
        self.plot_widget.addItem(start_point)
        self.plot_widget.addItem(end_point)
        self.line_item = [line, start_point, end_point]

    # 单线条
    # def drawConnectingLine(self):
    #     # 移除已存在的连接线和端点
    #     for item in self.line_item:
    #         self.plot_widget.removeItem(item)
    #
    #     # 获取点击点的坐标
    #     points = self.clicked_points
    #
    #     # 创建并添加线段
    #     x = [point[0] for point in points]
    #     y = [point[1] for point in points]
    #     line = pg.PlotCurveItem(x=x, y=y, pen=pg.mkPen(color='g', width=2, style=QtCore.Qt.DashLine))
    #     self.plot_widget.addItem(line)
    #
    #     # 创建端点的形状
    #     for point in points:
    #         x, y = point
    #         end_point = pg.ScatterPlotItem(x=[x], y=[y], symbol='o', size=10, pen='g', brush='g')
    #         self.plot_widget.addItem(end_point)
    #         self.line_item.append(end_point)
    #
    #     # 将线段保存到line_item列表中
    #     self.line_item.append(line)

    def mouseMoved(self, evt):
        if not self.timestamps:
            return
        pos = self.plot_widget.mapFromScene(evt)
        if self.plot_widget.sceneBoundingRect().contains(pos):
            mousePoint = self.plot_widget.plotItem.vb.mapSceneToView(pos)
            index = self.find_nearest_index(mousePoint.x(), self.timestamps)
            if index is not None:
                x_val = datetime.datetime.fromtimestamp(self.timestamps[index]).strftime("%H:%M:%S.%f")[:-3]
                y_val = self.data[index]
                # 设置字体大小
                font = QFont()
                font.setPointSize(12)  # 设置字体大小为12
                self.text_item.setFont(font)
                self.text_item.setText(f"x = {x_val}\ny = {y_val}", color=(0, 255, 0))
                # 限制Y轴大小变动
                # y_min, y_max = self.plot_widget.getPlotItem().getViewBox().viewRange()[1]
                # y_pos = max(min(mousePoint.y(), y_max), y_min)
                self.text_item.setPos(mousePoint.x(), mousePoint.y())
                self.text_item.show()
            self.vLine.setPos(mousePoint.x())
            self.hLine.setPos(mousePoint.y())
        else:
            self.text_item.hide()

    @staticmethod
    def find_nearest_index(x, data):
        if len(data) == 0:
            return None
        idx = min(range(len(data)), key=lambda i: abs(data[i] - x))
        return idx

    def update_data(self, value):
        if value != None:
            # 生成当前时间戳和随机整数数据
            timestamp = datetime.datetime.now().timestamp()
            # 将数据添加到列表
            self.timestamps.append(timestamp)
            self.data.append(float(value))

            # 更新图形数据
            self.plot.setData(x=self.timestamps, y=self.data)

            # 设置X轴范围为最后一分钟的数据
            if self.timestamps:
                xmin = max(timestamp - 60, min(self.timestamps))
                xmax = max(self.timestamps)
                self.plot_widget.setXRange(xmin, xmax)
            else:
                self.plot_widget.setXRange(0, 1)
            # 显示时间戳
            self.plot_widget.getPlotItem().setAxisItems({'bottom': self.date_axis})
